﻿/*
 * Rappelz: Endless Odyssey - The first free open source Rappelz server emulator
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Rappelz.GameServer.Network;
using System.Data.Common;
using System.Data;
using Rappelz.GameServer.Network.GameClient;

namespace Rappelz.GameServer.Database
{
    /// <summary>
    /// DB_CheckCharacterName
    /// </summary>
    public class DB_DeleteCharacter : IDBProc
    {
        private string m_Name;
        private string m_szAccountName;
        private int m_nAccountId;
        private TCPConnection m_client;
// 
// Data           :   this+0x160, Member, Type: struct IStreamSocketConnection *, pConnection
// Data           :   this+0x164, Member, Type: int, nAccountID
// Data           :   this+0x168, Member, Type: char[0x3D], szAccountName
// Data           :   this+0x1A8, Member, Type: class _bstr_t, szCharacterName


        private enum DBFields : int
        {
            Count = 0,
        }

        BaseObject m_CBObject;

        public void SetCB(BaseObject obj)
        {
            m_CBObject = obj;
        }

        public void RunCB()
        {
            if (m_CBObject != null)
                m_CBObject.onEndQuery();
        }

        public DB_DeleteCharacter(TCPConnection client, string szAccountName, string szName, int nAccountID)
        {
            m_client = client;
            m_Name = szName;
            m_nAccountId = nAccountID;
            m_szAccountName = szAccountName;
        }

        public bool onProcess()
        {
            if (this.proc())
            {
//                 g_ConnectionTagLock.baseclass_0.vfptr->Lock(&g_ConnectionTagLock);
//                 g_ConnectionTagLock.baseclass_0.m_pszFileName = "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Game\\Db\\DB_DeleteCharacter.cpp : DB_DeleteCharacter::onProcess";
//                 g_ConnectionTagLock.baseclass_0.m_nLineNumber = 273;
//                 *(v2 - 16) = &g_ConnectionTagLock;
                for(int i = this.m_client.Tag.vCharacterNameList.Count-1; i >= 0;--i)
                {
                    string str = this.m_client.Tag.vCharacterNameList[i];
                    if(str == this.m_Name)
                    {
                        this.m_client.Tag.vCharacterNameList.RemoveAt(i);
                        break;
                    }
                }
//                v10->UnLock(&g_ConnectionTagLock);
            }
//            XIOCPConnection::DecVar(v3->pConnection);
            return true;
        }

        private bool proc()
        {
            //dbo.smp_read_guild_party_id

            bool bNeedToBroadcastRaidInfo;      // 59   3Bh
            int nSID;                           // 92   5Ch
            int nPartyID;                       // 100  64h
            int nRaidLeaderGuildID;             // 104  68h
            int nGuildID;                       // 108  6Ch
            int nLeaderPartyID;                 // 108
            int nAllianceID;

            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd;

            try
            {
                cmd = conn.CreateCommand();
                cmd.CommandText = "dbo.smp_read_guild_party_id";
                cmd.CommandType = CommandType.StoredProcedure;

                DbParameter IN_NAME = GameDBManager.Instance.CreateInParameter(cmd, "IN_NAME", DbType.String, this.m_Name);
                DbParameter OUT_SID = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_SID", DbType.Int32);
                DbParameter OUT_GUILDID = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_GUILDID", DbType.Int32);
                DbParameter OUT_PARTYID = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_PARTYID", DbType.Int32);

                conn.Open();
                cmd.ExecuteNonQuery();
                nSID = (int)OUT_SID.Value;
                nGuildID = (int)OUT_GUILDID.Value;
                nPartyID = (int)OUT_PARTYID.Value;
                if (nSID == 0)
                {
                    Messages.SendResult(this.m_client, 2003, 1, 0);
                    if (conn != null && conn.State == ConnectionState.Open)
                        conn.Close();
                    return false;
                }
                if (nGuildID > 0)
                {
                    if (GuildManager.Instance.IsLeader(nGuildID, this.m_Name))
                    {
                        Messages.SendResult(this.m_client, 2003, 6, 0);
                        if (conn != null && conn.State == ConnectionState.Open)
                            conn.Close();
                        return false;
                    }

                    nAllianceID = GuildManager.Instance.GetAllianceID(nGuildID);
                    nRaidLeaderGuildID = nGuildID;
                    if (nAllianceID != 0)
                        nRaidLeaderGuildID = GuildManager.Instance.GetAllianceLeaderGuildID(nAllianceID);

                    if (GameRule.bLimitDungeonEnterableLevel)
                    {
                        if (GuildManager.Instance.IsRaidLeader(nRaidLeaderGuildID, this.m_Name))
                        {
                            Messages.SendResult(this.m_client, 2003, 5, 0);
                            if (conn != null && conn.State == ConnectionState.Open)
                                conn.Close();
                            return false;
                        }
                    }

                    Messages.PrintfGuildChatMessage(110, nGuildID, "LEAVE|{0}|", this.m_Name);
                    GuildManager.Instance.LeaveGuild(nGuildID, this.m_Name);
                }
                if (nPartyID != 0)
                {
                    if (PartyManager.Instance.IsLeader(nPartyID, this.m_Name))
                    {
                        bNeedToBroadcastRaidInfo = PartyManager.Instance.IsAttackTeamParty(nPartyID);
                        nLeaderPartyID = PartyManager.Instance.GetAttackTeamLeadPartyID(nPartyID);
                        Messages.BroadcastPartyDestroy(nPartyID);
                        PartyManager.Instance.DestroyParty(nPartyID);
                        if (bNeedToBroadcastRaidInfo && nLeaderPartyID != nPartyID)
                            Messages.BroadcastAttackTeamInfo(nLeaderPartyID);

                    }
                    else
                    {
                        Messages.PrintfPartyChatMessage(100, nPartyID, "LEAVE|{0}|", this.m_Name);
                        ServerLog.Log((ushort)0xD4C,this.m_nAccountId,0,nPartyID,0,0,0,2,0,0,0,0,this.m_szAccountName,this.m_Name,PartyManager.Instance.GetPartyName(nPartyID),"");
                        PartyManager.Instance.LeaveParty(nPartyID, this.m_Name);
                        if (PartyManager.Instance.IsAttackTeamParty(nPartyID))
                            Messages.BroadcastAttackTeamInfo(nPartyID);
                    }
                }

                if (conn != null && conn.State == ConnectionState.Open)
                    conn.Close();

                cmd = conn.CreateCommand();
                cmd.CommandText = "dbo.smp_read_friends_list";
                cmd.CommandType = CommandType.StoredProcedure;

                DbParameter IN_OWNER_ID = GameDBManager.Instance.CreateInParameter(cmd, "IN_OWNER_ID", DbType.String, this.m_Name);

                conn.Open();
                cmd.ExecuteNonQuery();

                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                while (dr.Read())
                {
                    String friend_id = dr.GetString(0);
                    uint player_id = (uint)Player.FindPlayer(friend_id);
                    Player player = Player.get(player_id) as Player;
                    if (player != null)
                    {
                        player.DelFriendOf(this.m_Name);
                    }
                }

                if (conn != null && conn.State == ConnectionState.Open)
                    conn.Close();

                cmd = conn.CreateCommand();
                cmd.CommandText = "dbo.smp_read_friendofs_list";
                cmd.CommandType = CommandType.StoredProcedure;

                IN_OWNER_ID = GameDBManager.Instance.CreateInParameter(cmd, "IN_OWNER_ID", DbType.String, this.m_Name);

                conn.Open();
                cmd.ExecuteNonQuery();  //Fixme: we call cmd.ExecuteReader() after

                dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                while (dr.Read())
                {
                    String friend_id = dr.GetString(0);
                    uint player_id = (uint)Player.FindPlayer(friend_id);
                    Player player = Player.get(player_id) as Player;
                    if (player != null)
                    {
                        player.DelFriend(this.m_Name);
                        Messages.SendFriendsList(player);
                    }
                }

                if (conn != null && conn.State == ConnectionState.Open)
                    conn.Close();

                cmd = conn.CreateCommand();
                cmd.CommandText = "dbo.smp_read_denials_list";
                cmd.CommandType = CommandType.StoredProcedure;

                IN_OWNER_ID = GameDBManager.Instance.CreateInParameter(cmd, "IN_OWNER_ID", DbType.String, this.m_Name);

                conn.Open();
                cmd.ExecuteNonQuery();  //Fixme: we call cmd.ExecuteReader() after

                dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                while (dr.Read())
                {
                    String friend_id = dr.GetString(0);
                    uint player_id = (uint)Player.FindPlayer(friend_id);
                    Player player = Player.get(player_id) as Player;
                    if (player != null)
                    {
                        player.DelDenialOf(this.m_Name);
                    }
                }

                if (conn != null && conn.State == ConnectionState.Open)
                    conn.Close();

                cmd = conn.CreateCommand();
                cmd.CommandText = "dbo.smp_read_denialofs_list";
                cmd.CommandType = CommandType.StoredProcedure;

                IN_OWNER_ID = GameDBManager.Instance.CreateInParameter(cmd, "IN_OWNER_ID", DbType.String, this.m_Name);

                conn.Open();
                cmd.ExecuteNonQuery();  //Fixme: we call cmd.ExecuteReader() after

                dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                while (dr.Read())
                {
                    String friend_id = dr.GetString(0);
                    uint player_id = (uint)Player.FindPlayer(friend_id);
                    Player player = Player.get(player_id) as Player;
                    if (player != null)
                    {
                        player.DelDenial(this.m_Name);
                        Messages.SendDenialsList(player);
                    }
                }

                if (conn != null && conn.State == ConnectionState.Open)
                    conn.Close();

                cmd = conn.CreateCommand();
                cmd.CommandText = "dbo.smp_delete_character";
                cmd.CommandType = CommandType.StoredProcedure;

                IN_NAME = GameDBManager.Instance.CreateInParameter(cmd, "IN_NAME", DbType.String, this.m_Name);
                OUT_SID = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_SID", DbType.Int32);

                conn.Open();
                cmd.ExecuteNonQuery();

                Messages.SendResult(this.m_client, 2003, 0, 0);

                nSID = (int)OUT_SID.Value;
                
                if (nSID == 0)
                {
                    if (conn != null && conn.State == ConnectionState.Open)
                        conn.Close();
                    return false;
                }

                RankingManager.Instance.DeleteRankingScore(nSID);
                ServerLog.Log((ushort)2004,this.m_nAccountId,nSID,0,0,0,0,0,0,0,0,0,
                    this.m_szAccountName,this.m_Name,"","");

                if (conn != null && conn.State == ConnectionState.Open)
                    conn.Close();

            }
            catch (System.Exception ex)
            {
                Globals.Log.Error("Error in DB_DeleteCharacter.proc: {0}", ex);
            }

            return true;
        }

    }

}
